/*
 * LocalMonitor.cpp  0.4.0 / Nov 14, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "LocalMonitor.h"

// LocalMonitor :: Public Constructor. -----------------------------------------

/*!
 * \brief Constructs new LocalMonitor object.
 *
 * \param env the JNIEnv pointer
 * \param obj the Java object
 * \param lockField the lock field of the object
 */
LocalMonitor::LocalMonitor(JNIEnv *env, jobject obj, jfieldID lockField)
  : m_env(env), m_entered(false)
{
  Q_ASSERT(env);
  Q_ASSERT(obj);
  if (lockField) {
    m_obj = env->GetObjectField(obj, lockField);
  } else {
    m_obj = obj;
  }
  Q_ASSERT(m_obj);
}

// LocalMonitor :: Destructor. -------------------------------------------------

/*!
 * \brief Destroys the LocalMonitor object.
 */
LocalMonitor::~LocalMonitor()
{
  exit();
}

// LocalMonitor :: Private Constructor. ----------------------------------------

LocalMonitor::LocalMonitor(const LocalMonitor &)
{
  // copy constructor is disabled.
}

// LocalMonitor :: Public Member Functions. ------------------------------------

/*!
 * \brief Enters the monitor.
 *
 * \return \c true if succeed
 */
bool LocalMonitor::enter()
{
  if (!m_entered) {
    if (!m_env->MonitorEnter(m_obj)) {
      m_entered = true;
      return true;
    } else {
      if (m_env->ExceptionCheck()) {
        m_env->ExceptionDescribe();
        m_env->ExceptionClear();
      }
    }
  }
  return false;
}

/*!
 * \brief Exits the monitor.
 *
 * \return \c true if succeed
 */
bool LocalMonitor::exit()
{
  if (m_entered) {
    if (!m_env->MonitorExit(m_obj)) {
      m_entered = false;
      return true;
    } else {
      if (m_env->ExceptionCheck()) {
        m_env->ExceptionDescribe();
        m_env->ExceptionClear();
      }
    }
  }
  return false;
}
